package com.zx.zhilian;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zx.common.HttpUtils;

/**
 * @Project: my_spider
 * @Title: Main
 * @Description: 抓取智联
 * @author: zhangxue
 * @date: 2017年12月4日下午9:46:40
 * @company: webyun
 * @Copyright: Copyright (c) 2015
 * @version v1.0
 */
public class Main {
	
	private static Logger LOGGER = LoggerFactory.getLogger(Main.class);
	
	public static void main(String[] args) {
		ZhiLianDao zhiLianDao = new ZhiLianDao();
		try {
			zhiLianDao.createTable();
		} catch (SQLException e) {
			LOGGER.error("智联表初始化异常");
			LOGGER.error(e.getMessage(), e);
		}
		List<ZhiLianKeys> startUrls = getStartUrls();
		LOGGER.info("通过关键词生产所有的搜索页，共【{}】个", startUrls.size());
		int keyIndex = 0;//城市的序号
		int pageIndex = 0;//该城市第几页的序号
		
		for (ZhiLianKeys zhiLianKeys : startUrls) {
			String jobName = zhiLianKeys.getJobName();
			String placeName = zhiLianKeys.getPlaceName();
			String keyUrl = zhiLianKeys.getUrl();
			
			pageIndex = 0;//初始化该城市第几页的序号
			
			LOGGER.info("第一步:第【{}】个url=【{}】,通过关键词jobName=【{}】,placeName=【{}】获得", keyIndex + 1, keyUrl, jobName, placeName);
			// 获得这个关键词下所有的内容
			try {
				boolean isNextPage = true;//是否解析下一页
				// 注意：所以对比上一页和本页产品的URL,如果完全相同，这说明这个关键词搜索的内容已经全部结束了
				List<String> keyUrlPrev = new ArrayList<>();//上一页的URL
				List<String> keyUrlPages = new ArrayList<>();//本页的URL
				
				while (isNextPage) {
					String pageUrl = keyUrl + "&p=" + (pageIndex + 1);
					try {
						keyUrlPages = getPageUrls(pageUrl);
						
						for (String url : keyUrlPages) {
							try {
								ZhiLian model = getModel(url, jobName);
								if(model != null) {
									zhiLianDao.insert(model);
									LOGGER.info("jobName=【{}】,placeName=【{}】,url=【{}】", jobName, placeName, url);
								}
							} catch (Exception e) {
								LOGGER.error("该职位或该公司数据不全，舍去。jobName=【{}】,placeName=【{}】,url=【{}】", jobName, placeName, url);
								LOGGER.error(e.getMessage(), e);
							}
						}
						isNextPage = isNextPage(keyUrlPrev, keyUrlPages);
					} catch (Exception e) {
						LOGGER.error("第三步:获取room url异常，位置keyIndex={}, pageIndex={}", keyIndex, pageIndex);
						LOGGER.error(e.getMessage(), e);
					}
					pageIndex ++;
					keyUrlPrev = keyUrlPages;//将这一页的url，赋值为上一个的url
					
					if(pageIndex > 200)//页数不可能太大的，超过200就是异常了
						isNextPage = false;
				}
				
			} catch (Exception e) {
				LOGGER.error("第二步:获取这个城市所有分页异常，位置keyIndex={}, pageIndex={}", keyIndex, pageIndex);
				LOGGER.error(e.getMessage(), e);
			}
			keyIndex ++;
		}
	}
	
	/**
	 * @Title: 得到不同城市的起始链接
	 * @return
	 * @date: 2017年12月4日下午9:51:40
	 */
	public static List<ZhiLianKeys> getStartUrls(){
	    //先主要爬主要城市，看不同需求，也可以爬全国，只要把智联的候选地点全部抓取下来即可
		String[] placeNames = {"北京","上海", "广州", "深圳", "天津", "武汉", "西安", "成都", "大连", "长春", "沈阳", "南京", "济南", "青岛",
	                   "杭州", "苏州", "无锡", "宁波", "重庆", "郑州", "长沙", "福州", "厦门", "哈尔滨", "石家庄", "合肥", "惠州"};
		String[] jobNames = {"大数据", "java", "cobol"};
		List<ZhiLianKeys> totalUrls = new ArrayList<>();
		for (String jobName : jobNames) {
			for (String placeName : placeNames) {
				String url = "http://sou.zhaopin.com/jobs/searchresult.ashx?jl=" + placeName + "&kw=" + jobName;
				totalUrls.add(new ZhiLianKeys(jobName, placeName, url));
			}
		}
		return totalUrls;
	}
	
	public static List<String> getPageUrls(String pageUrl) throws Exception {
		List<String> urls = new ArrayList<>(60);
		try {
			String content = HttpUtils.get(pageUrl, null);
			Document doc=Jsoup.parse(content); // 解析网页 得到文档对象
			
	        Elements linkElements=doc.select("#newlist_list_content_table table tr td div a");
	        for(Element e:linkElements){
	        	String attr = e.attr("href");
	        	if(attr.startsWith("http://"))
	        		urls.add(e.attr("href"));
	        }
	        return urls;
		} catch (Exception e){
			throw e;
		} 
	}
	
	public static ZhiLian getModel(String url, String keyName) throws Exception {
		try {
			String content = HttpUtils.get(url, null);
			Document doc=Jsoup.parse(content); // 解析网页 得到文档对象
	        String 职位名称 = doc.select(".fixed-inner-box .fl h1").text();
	        String 职位链接 = url;
	        String 公司名称 = doc.select(".fixed-inner-box .fl h2 a").text();
	        String 公司链接 = doc.select(".fixed-inner-box .fl h2 a").attr("href");
	        
	        StringBuffer 公司福利Temp = new StringBuffer("");
	        doc.select(".fixed-inner-box .fl div span").forEach(ele ->  {
	        	公司福利Temp.append(",").append(ele.text());
	        });
	        String 公司福利 = 公司福利Temp.toString().isEmpty() ? "" : 公司福利Temp.substring(1);
	        
	        Elements lis = doc.getElementsByClass("terminal-ul clearfix").select("li");
	        String 职位月薪 = lis.get(0).getElementsByTag("strong").get(0).text();
	        String 工作地点 = lis.get(1).getElementsByTag("strong").get(0).text();
	        String 发布日期 = lis.get(2).getElementById("span4freshdate").text();
	        String 工作性质 = lis.get(3).getElementsByTag("strong").get(0).text();
	        String 工作经验 = lis.get(4).getElementsByTag("strong").get(0).text();
	        String 最低学历 = lis.get(5).getElementsByTag("strong").get(0).text();
	        String 招聘人数 = lis.get(6).getElementsByTag("strong").get(0).text();
	        String 职位类别 = lis.get(7).getElementsByTag("a").get(0).text();
	        
	        String 详细工作地点 = doc.select(".tab-inner-cont h2").text();
	        String 公司介绍 = doc.select(".tab-inner-cont").get(1).getElementsByTag("p").text();
	        
	        Elements companyConetnt = doc.getElementsByClass("terminal-ul clearfix terminal-company mt20").select("li strong");
	        
	        if(companyConetnt.size() != 5) {// 公司信息不全的舍去
	        	throw new Exception("该公司信息不全应该舍去(可能是官网地址缺失)");
	        }
	        String 公司规模 = companyConetnt.get(0).text();
	        String 公司性质 = companyConetnt.get(1).text();
	        String 公司行业 = companyConetnt.get(2).text();
	        String 公司主页 = companyConetnt.get(3).text();
	        String 公司地址 = companyConetnt.get(4).text();
	        
	        String 关键词 = keyName;
	        
	        return new ZhiLian(null, 职位名称, 职位链接, 公司名称, 公司链接, 公司福利, 职位月薪, 工作地点, 
	        		发布日期, 工作性质, 工作经验, 最低学历, 招聘人数, 职位类别, 职位类别, 详细工作地点,
	        		公司介绍, 公司规模, 公司性质, 公司行业, 公司主页, 公司地址, 关键词);
		} catch (Exception e){
			throw e;
		} 
	}
	
	/**
	 * @Title: 是否继续解析下一页
	 * @param prevUrl
	 * @param pageUrl
	 * @Description: TODO
	 * @date: 2017年12月3日下午9:39:56
	 */
	public static boolean isNextPage (List<String> prevUrl, List<String> pageUrl) {
		return !prevUrl.containsAll(pageUrl);
	}
}
